-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Go: Promote non-httponly cookie query, and add insecure cookie query #20762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
d00f670 to
2805a60
Compare
|
QHelp previews: go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.qhelpCookie 'HttpOnly' attribute is not set to trueCookies without the RecommendationSet the ExampleIn the following example, in the case marked BAD, the package main
import (
"net/http"
)
func handlerBad(w http.ResponseWriter, r *http.Request) {
c := http.Cookie{
Name: "session",
Value: "secret",
}
http.SetCookie(w, &c) // BAD: The HttpOnly flag is set to false by default.
}
func handlerGood(w http.ResponseWriter, r *http.Request) {
c := http.Cookie{
Name: "session",
Value: "secret",
HttpOnly: true,
}
http.SetCookie(w, &c) // GOOD: The HttpOnly flag is set to true.
}References
go/ql/src/Security/CWE-614/CookieWithoutSecure.qhelpCookie 'Secure' attribute is not set to trueCookies without the RecommendationSet the ExampleIn the following example, in the case marked BAD, the package main
import (
"net/http"
)
func handlerBad(w http.ResponseWriter, r *http.Request) {
c := http.Cookie{
Name: "session",
Value: "secret",
}
http.SetCookie(w, &c) // BAD: The Secure flag is set to false by default.
}
func handlerGood(w http.ResponseWriter, r *http.Request) {
c := http.Cookie{
Name: "session",
Value: "secret",
Secure: true,
}
http.SetCookie(w, &c) // GOOD: The Secure flag is set to true.
}References
|
6f26b83 to
999eff1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR promotes an experimental query for detecting cookies without the HttpOnly flag and introduces a new query for detecting cookies without the Secure flag. The changes include:
- Migration of the
CookieWithoutHttpOnlyquery from experimental to the main security query pack - Introduction of a new
CookieWithoutSecurequery - New shared library code (
SecureCookies.qll) for modeling HTTP cookie security attributes - Updates to framework models for
net/httpandgin-gonic/gin
Reviewed Changes
Copilot reviewed 31 out of 42 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.ql | New query for detecting cookies without HttpOnly flag |
| go/ql/src/Security/CWE-614/CookieWithoutSecure.ql | New query for detecting cookies without Secure flag |
| go/ql/lib/semmle/go/security/SecureCookies.qll | Shared library for cookie security analysis |
| go/ql/lib/semmle/go/concepts/HTTP.qll | Added CookieWrite and CookieOptions concepts |
| go/ql/lib/semmle/go/frameworks/NetHttp.qll | Added cookie write models for net/http |
| go/ql/lib/semmle/go/frameworks/Gin.qll | New framework models for gin-gonic/gin |
| go/ql/src/change-notes/2025-11-10-inseucre-cookie.md | Change notes documenting the updates |
| go/ql/src/experimental/CWE-1004/* | Removed experimental query files |
| go/ql/test/query-tests/Security/CWE-614/* | Test files for CookieWithoutSecure |
| go/ql/test/query-tests/Security/CWE-1004/* | Test files for CookieWithoutHttpOnly |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
owen-mc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love the new concepts. I think they make the structure quite clean, and allow us to add other libraries easily in future.
I've only done a partial review so far. It will be easier to continue once these points have been addressed.
I note that you've removed modelling and tests for github.com/gorilla/sessions. Was that deliberate? It seems like a popular enough library, and it's only a bit of extra modelling and some tests that have already been written.
|
Addressed comments |
owen-mc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for applying all those changes. On second thought, maybe it's too much work to add modeling for Gorilla. You can leave it for now. But please remove the stubs for it, and mentions of it from the go.mod and modules.txt files.
My only slight worry is that performance might be bad in certain situations. Let me explain. For the insecure cookie query, to get the best performance I think you would have two data flow configs: one from getCookieOutput() of CookieOptionsWrite for getSecure exists to CookieWrite, and one from any boolean typed node with getBooleanValue() = false to the getSecure() of a CookieOptionsWrite (for extra performance you would also require that the getCookieOutput() of it is a source a path for the first data flow config. By using just one config you've made is simpler, but you could end up with lots of sources along the same path, and hence lots of paths. Maybe that's okay performance-wise. But the DCA run seems fine, so no need to change anything - we can always look into it in future if needed.
| /** Provides a class for modeling the new APIs for writes to options of an HTTP cookie. */ | ||
| module CookieOptionWrite { | ||
| /** | ||
| * A write to an HTTP cookie object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * A write to an HTTP cookie object. | |
| * A write to an option of an HTTP cookie object. |
| * A write to an HTTP cookie object. | ||
| * | ||
| * Extend this class to model new APIs. If you want to refine existing API models, | ||
| * extend `HTTP::CookieOptions` instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * extend `HTTP::CookieOptions` instead. | |
| * extend `HTTP::CookieOptionWrite` instead. |
| } | ||
|
|
||
| /** | ||
| * A write to an HTTP cookie object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * A write to an HTTP cookie object. | |
| * A write to an option of an HTTP cookie object. |
| * A write to an HTTP cookie object. | ||
| * | ||
| * Extend this class to refine existing API models. If you want to model new APIs, | ||
| * extend `HTTP::CookieOptions::Range` instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * extend `HTTP::CookieOptions::Range` instead. | |
| * extend `HTTP::CookieOptionWrite::Range` instead. |
| Http::CookieWrite cw, string name, SensitiveCookieNameFlow::PathNode source, | ||
| SensitiveCookieNameFlow::PathNode sink | ||
| where | ||
| isSensitiveCookie(cw, name, source, sink) and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name isn't used in the select clause, and this predicate isn't called anywhere else, so you can remove that argument from the predicate. And then you can delete isSource(DataFlow::Node source, string val) and just put all the logic in `isSource(DataFlow::Node source).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove mentions of gorilla from this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove mentions of gorilla from this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this file.
| # github.com/gorilla/sessions v1.2.1 | ||
| ## explicit | ||
| github.com/gorilla/sessions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # github.com/gorilla/sessions v1.2.1 | |
| ## explicit | |
| github.com/gorilla/sessions |
|
|
||
| require ( | ||
| github.com/gin-gonic/gin v1.7.1 | ||
| github.com/gorilla/sessions v1.2.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| github.com/gorilla/sessions v1.2.1 |
|
Have you checked how autofix works on these queries? |
Promotes
go/cookie-httponly-not-setfrom experimental, and addsgo/cookie-secure-not-setquery.